/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.tactics;

import robocup.component.SConf;
import robocup.component.ControllerNumbers.PLAY_MODE;
import robocup.component.ControllerNumbers.STAMINA_LEVEL;
import robocup.component.actionfactories.BasicActionFactory;
import robocup.component.geometry.Vektor;
import robocup.component.situations.SituationEvaluator;
import robocup.component.situations.SituationEvaluator.TYPE;

/**
 * This state defines the behaviour of the goalie after catching the ball. 
 * Then, he is able to move twice inside his penalty area in order to make 
 * a kick-in.
 */
public class GoalieKickInState extends AbstractState {

	private static Vektor posToMoveFreeKick1 = new Vektor();

	private static Vektor posToMoveFreeKick2 = new Vektor();

	private static Vektor posToMoveBeforeGoalKick1 = new Vektor();

	private static Vektor posToMoveBeforeGoalKick2 = new Vektor();

	private static Vektor posToMoveGoalKick = new Vektor();

	private double benefit = 0;

	// private static boolean debug = false;
	int i = 0;

	// private double passAngle = 0;

	private int cycles = 0;

	private int moveCycle = 0;

	// private int receiverNum = 0;

	private double neededBenefit = 0;

	// private Ball dummyBall = null;

	private boolean foundPass = false;

	// private ReachableArea gra = new ReachableArea();

	// private SConf sConf = SConf.getInstance();

	/**
	 * Construktor Goal-Kick State. Makes the gaolie to kick the ball after
	 * catching.
	 * 
	 * @param parent -
	 *            the StateEvaluation
	 */
	public GoalieKickInState(StateEvaluation parent) {

		super(parent);
		this.state = STATES.GOALIE_KICK_IN;

	}

	/**
	 * Only executable in special play-modes!
	 */
	@Override
	public boolean preCondition() {

		return checkPlayMode()
				&& (!(getWorld().getPlayMode() == PLAY_MODE.FREE_KICK_OWN) || this
						.checkPlayerHasBall()) && getWorld().isGoalie();
	}

	/**
	 * Action never fails!
	 */
	@Override
	protected double successProbability() {

		return 1;
	}

	/**
	 * No concurrent actions available up to now!
	 */
	@Override
	protected double successBenefit() {
		benefit = SituationEvaluator.getValue(TYPE.PASSING, getWorld()
				.getMyPosition(), getWorld().getMyPosition(), 2, 1, getWorld()
				.getSelfRef(), getWorld());
		return benefit;
	}

	@Override
	public void calculateMainAction() {
		benefit = 0.1;
		posToMoveFreeKick1.x = this.parent.getSConf().half_penalty_width - 2;
		posToMoveFreeKick1.y = SConf.getInstance().GOAL_POS_OWN.y
				+ this.parent.getSConf().penalty_length - 2;
		posToMoveFreeKick2.x = -this.parent.getSConf().half_penalty_width + 2;
		posToMoveFreeKick2.y = SConf.getInstance().GOAL_POS_OWN.y
				+ this.parent.getSConf().penalty_length - 2;
		if (getWorld().getBallRef().getPosition().x < getWorld()
				.getMyPosition().x) {
			posToMoveBeforeGoalKick1.x = getWorld().getBallRef().getPosition().x + 3;
			posToMoveBeforeGoalKick1.y = getWorld().getBallRef().getPosition().y;
		} else {
			posToMoveBeforeGoalKick1.x = getWorld().getBallRef().getPosition().x - 3;
			posToMoveBeforeGoalKick1.y = getWorld().getBallRef().getPosition().y;
		}
		posToMoveBeforeGoalKick2.x = getWorld().getBallRef().getPosition().x;
		posToMoveBeforeGoalKick2.y = getWorld().getBallRef().getPosition().y - 3;

		posToMoveGoalKick.x = getWorld().getBallRef().getPosition().x;
		posToMoveGoalKick.y = getWorld().getBallRef().getPosition().y
				- this.parent.getSConf().BALL_SIZE
				- getWorld().getMyPConf().PLAYER_SIZE - 0.05;
		if (PLAY_MODE.GOAL_KICK_OWN == getWorld().getPlayMode()) {
			// System.out.println(getWorld().getCycleAndPlayerString()+" goalie
			// pass benefit: "+getProphet().getPassBenefit());
			if (getWorld().getCycle() > this.moveCycle + 3) {
				this.i = 0;
			}
			if (this.i == 0) {
				this.moveCycle = getWorld().getCycle();
				mainAction = BasicActionFactory.moveToPos(getWorld(),
						posToMoveBeforeGoalKick1, STAMINA_LEVEL.HIGH);
				if (getWorld().getMyNextPosition().getDistance(
						posToMoveBeforeGoalKick1) < 0.5) {
					this.i = 1;
				}
			} else if (this.i == 1) {
				this.moveCycle = getWorld().getCycle();
				mainAction = BasicActionFactory.moveToPos(getWorld(),
						posToMoveBeforeGoalKick2, STAMINA_LEVEL.HIGH);
				if (getWorld().getMyNextPosition().getDistance(
						posToMoveBeforeGoalKick2) < 0.5) {
					this.i = 2;
				}
			} else if (this.i == 2) {
				this.moveCycle = getWorld().getCycle();
				mainAction = BasicActionFactory.moveToPos(getWorld(),
						posToMoveGoalKick, STAMINA_LEVEL.HIGH);
				if (getWorld().getMyNextPosition().getDistance(
						posToMoveGoalKick) < 0.4) {
					this.i = 3;
				}
			} else if (this.i == 3) {
				this.moveCycle = getWorld().getCycle();
				mainAction = BasicActionFactory.turnBodyToPoint(getWorld(),
						SConf.getInstance().GOAL_POS_OTHER);
				if (Math.abs(getWorld().getBodyAngle()) < 45) {
					this.i = 4;
					this.cycles = 0;
				}
			} else if (this.i == 4) {
				if (getWorld().getCycle() > this.moveCycle) {
					if (Math.abs(getWorld().getBodyAngle()) > 45) {
						i = 3;
					}
					this.cycles++;
					if (this.getProphet().canPass()
							&& this.getProphet().getPassBenefit() > 0.10) {
						this.i = 0;
						this.moveCycle = getWorld().getCycle();
						mainAction = getProphet().getPassAction();
					}
				}

				if (getWorld().getCycle() > this.moveCycle) {
					if (this.cycles > 90) {
						this.i = 0;
						this.moveCycle = getWorld().getCycle();
						if (getWorld().getMyPosition().x > 0) {
							mainAction = BasicActionFactory.kickFastest(
									getWorld().getSelfRef(), getWorld()
											.getBallRef(),
									SConf.getInstance().CORNER_RIGHT_OWN);
						} else {
							mainAction = BasicActionFactory.kickFastest(
									getWorld().getSelfRef(), getWorld()
											.getBallRef(),
									SConf.getInstance().CORNER_LEFT_OWN);
						}
					}
				}
				this.moveCycle = getWorld().getCycle();
			}
		} else if (PLAY_MODE.FREE_KICK_OWN == getWorld().getPlayMode()) {
			// System.out.println(getWorld().getCycleAndPlayerString()+" goalie
			// pass benefit: "+getProphet().getPassBenefit());
			if (getWorld().getCycle() - 3 > this.moveCycle) {
				this.i = 0;
			}
			if (getWorld().getCycle() > this.moveCycle) {
				if (this.i == 0) {
					this.moveCycle = getWorld().getCycle();
					this.foundPass = false;
					mainAction = BasicActionFactory
							.move(GoalieKickInState.posToMoveFreeKick1);
					this.i = 1;
					this.cycles = 0;
				}
			}

			if (getWorld().getCycle() > this.moveCycle) {
				if (this.i == 1 && this.cycles < 70) {
					this.moveCycle = getWorld().getCycle();
					// neededBenefit= Math.max(Math.min(1, (1 -(cycles *
					// 0.02))),0.5);
					this.neededBenefit = 0.15;
					this.cycles++;
					// find second pass
					// getWorld().setGoalieWMAsMoved(posToMoveFreeKick2);
					// getProphet().calculateNewPass();
					//					
					// if (getProphet().getPassBenefit() >= neededBenefit &&
					// getProphet().canPass()) {
					// debugOut("found pass from 2. freekick pos");
					// foundPass= true;
					// }
					// getWorld().setGoalieBeforeMoved();

					if (this.foundPass) {
						// move
						mainAction = BasicActionFactory
								.move(GoalieKickInState.posToMoveFreeKick2);
						this.i = 2;
					} else {
						// try direct pass
						if (getProphet().canPass()
								&& getProphet().getPassBenefit() >= this.neededBenefit) {
							mainAction = this.getProphet().getPassAction();
							this.i = 0;
						}
						// turn to field
						else {
							mainAction = BasicActionFactory.turnBodyToPoint(
									getWorld(),
									SConf.getInstance().GOAL_POS_OTHER);
						}
					}
				}
			}

			if (getWorld().getCycle() > this.moveCycle) {
				if (this.i == 1 && this.cycles >= 70) {
					this.moveCycle = getWorld().getCycle();
					this.cycles++;
					mainAction = BasicActionFactory
							.move(GoalieKickInState.posToMoveFreeKick2);
					this.i = 2;
				}
			}

			if (getWorld().getCycle() > this.moveCycle) {
				if (this.i == 2 && this.cycles <= 90) {
					this.moveCycle = getWorld().getCycle();
					// neededBenefit= Math.max(Math.min(1, (1 -(cycles *
					// 0.02))),0.5);
					this.neededBenefit = 0.15;
					this.cycles++;
					if (this.getProphet().canPass()
							&& this.getProphet().getPassBenefit() >= this.neededBenefit) {
						mainAction = this.getProphet().getPassAction();
						this.i = 0;
					}
				}
			}

			if (getWorld().getCycle() > this.moveCycle) {
				if (this.i == 2 && this.cycles > 90) {
					this.moveCycle = getWorld().getCycle();
					// neededBenefit= Math.max(Math.min(1, (1 -(cycles *
					// 0.02))),0.5);
					this.neededBenefit = 0.15;
					this.cycles++;
					if (getWorld().getMyPosition().x > 0) {
						mainAction = BasicActionFactory.kickFastest(getWorld()
								.getSelfRef(), getWorld().getBallRef(), SConf
								.getInstance().CORNER_RIGHT_OWN);
					} else {
						mainAction = BasicActionFactory.kickFastest(getWorld()
								.getSelfRef(), getWorld().getBallRef(), SConf
								.getInstance().CORNER_LEFT_OWN);
					}
					this.i = 0;
				}
			}

		}

	}

}
